/*
 * Copyright (C) 2007-2008 SlideMe client
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.slideme.android.sdk.installer;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.URL;
import java.net.HttpURLConnection;
import java.util.logging.Logger;
import java.util.Random;
import java.util.Arrays;

public class ApplicationInstallerSocketService {

    private static Logger logger = Logger.getAnonymousLogger();

    public static void main(String args[]) {
        ServerSocket serverSocket;
        Socket clientSocket;
        try {
            serverSocket = new ServerSocket(8090, 5);
        } catch (IOException e) {
            logger.severe("Unable to start server socket: port 8090");
            return;
        }

        while (true) {
            try {
                clientSocket = serverSocket.accept();
                clientSocket.setSoTimeout(1000);
            } catch (IOException e) {
                logger.info("Unable to accept client request.");
                continue;
            }

            try {
                (new InstallationRequestHandler(clientSocket)).start();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    private static class InstallationRequestHandler extends Thread {

        private Socket socket;

        InstallationRequestHandler(Socket socket) {
            this.socket = socket;
        }

        public void start() {
            StringBuffer url = new StringBuffer();
            byte[] buffer = new byte[256];

            InputStream is;
            try {
                is = socket.getInputStream();
            } catch (IOException e) {
                logger.info("Could not get inputstream from client: " + e.getMessage());
                try {
                    socket.close();
                } catch (IOException e1) {
                }
                return;
            }

            try {
                while ((is.read(buffer)) > 0) {
                    url.append(new String(buffer));
                }
            } catch (IOException e) {
                logger.info("Failed to read from client: Buffer = " + url);
            } finally {
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            logger.info("Received URL request from client: URL = " + url.toString());

            InputStream ins;
            FileOutputStream fos = null;

            String fileName = new File(System.getProperty("java.io.tmp"), new Random().nextLong() + ".apk")
                    .getAbsolutePath();

            try {
                URL contentURL = new URL(url.toString());
                HttpURLConnection connection = (HttpURLConnection) contentURL.openConnection();
                ins = connection.getInputStream();
                fos = new FileOutputStream(fileName);
                writeInputStreamToOutputStream(ins, fos);
            } catch (IOException e) {
                logger.info("There was an error obtaining the content from the catalog server.");
                e.printStackTrace();
            }
            finally {
                if (fos != null) {
                    try {
                        fos.close();
                    } catch (IOException e) {

                    }
                }
                if (fos != null) {
                    try {
                        fos.close();
                    } catch (IOException e) {

                    }
                }
            }
            logger.info("Saved android app file: File Name = " + fileName);
            String[] paths = System.getenv("Path").split(File.pathSeparator);

            File adbFile = null;
            for (String path : paths) {
                path = path.replace("\"", "").trim();
                adbFile = new File(path, "adb.exe");
                if (adbFile.exists()) {
                    break;
                }
            }
            if (adbFile == null || !adbFile.exists()) {
                logger.info("Could not find adb to install with. Check to make sure that it exists on your system path");
                return;
            }
            logger.info("Found adb file: File = " + adbFile.getAbsolutePath());

            try {
                Process process = Runtime.getRuntime().exec("\"" + adbFile.getAbsolutePath() + "\" install " + "\"" + fileName + "\"");
            } catch (IOException e) {
                logger.info("There was a problem installing the application");
                e.printStackTrace();
            }
            logger.info("Finished Installation.");
        }

        static private void writeInputStreamToOutputStream(InputStream is, OutputStream os) throws IOException {
            byte[] buffer = new byte[8192];
            int n;
            while ((n = is.read(buffer)) >= 0) {
                os.write(buffer, 0, n);
            }
        }
    }
}